package com.crb.crm.manage.oos.qiniu;

import com.crb.crm.manage.enums.OssType;
import com.crb.crm.manage.oos.OSSUtil;
import com.crb.crm.manage.utils.JSONUtils;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.ResponseBody;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

/**
 * 七牛云上传下载工具类
 *
 * @author simon
 * @create 2018-08-15 11:21
 **/
@Slf4j
@Component
class QiNiuUtil implements OSSUtil {

    @Resource
    private QiNiuConfig qiNiuConfig;

    private Auth getAuth() {
        Auth auth = Auth.create(qiNiuConfig.getAccessKey(), qiNiuConfig.getSecretKey());
        return auth;
    }

    /**
     * 获取文件访问地址
     *
     * @param key 文件云端存储的名称
     * @return
     * @throws UnsupportedEncodingException
     */
    private String fileUrl(String key) throws UnsupportedEncodingException {
        String encodedFileName = URLEncoder.encode(key, "utf-8");
        String publicUrl = String.format("%s/%s", qiNiuConfig.getDomainOfBucket(), encodedFileName);
        Auth auth = getAuth();
        long expireInSeconds = qiNiuConfig.getExpireInSeconds();
        if (-1 == expireInSeconds) {
            return auth.privateDownloadUrl(publicUrl);
        }
        return auth.privateDownloadUrl(publicUrl, expireInSeconds);
    }

    /**
     * 通过发送http get 请求获取文件资源
     *
     * @return
     */
    @Override
    public InputStream download(String key) {
        OkHttpClient client = new OkHttpClient();
        Request req;
        okhttp3.Response resp = null;
        try {
            String url = fileUrl(key);
            req = new Request.Builder().url(url).build();
            resp = client.newCall(req).execute();
            if (resp.isSuccessful()) {
                ResponseBody body = resp.body();
                InputStream is = body.byteStream();
                return is;
            }
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("Unexpected code " + resp);
        }
        return null;
    }


    @Override
    public OssType support() {
        return OssType.OSS_QINIU;
    }

    /**
     * 上传InputStream
     *
     * @param is
     * @param key
     * @return
     * @throws IOException
     */
    @Override
    public boolean upload(InputStream is, String key) {
        //构造一个带指定Zone对象的配置类
        Configuration cfg = new Configuration(Zone.zone2());
        //...其他参数参考类注释
        UploadManager uploadManager = new UploadManager(cfg);

        //把文件转化为字节数组
        ByteArrayOutputStream bos = null;

        try {
            bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int len = -1;
            while ((len = is.read(b)) != -1) {
                bos.write(b, 0, len);
            }
            byte[] uploadBytes = bos.toByteArray();

            Auth auth = getAuth();
            String upToken = auth.uploadToken(qiNiuConfig.getBucket(), key);
            //默认上传接口回复对象
            DefaultPutRet putRet;
            //进行上传操作，传入文件的字节数组，文件名，上传空间，得到回复对象
            Response response = uploadManager.put(uploadBytes, key, upToken);
            putRet = JSONUtils.json2pojo(response.bodyString(), DefaultPutRet.class);
            //key 文件名
            System.out.println(putRet.key);
            //hash 七牛返回的文件存储的地址，可以使用这个地址加七牛给你提供的前缀访问到这个视频。
            System.out.println(putRet.hash);
            return true;
        } catch (QiniuException e) {
            e.printStackTrace();
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * @param key 文件路径/名称，例如“test/a.txt”
     * @return void            返回类型
     * @throws
     * @Title: deleteFile
     * @Description: 根据key删除oss服务器上的文件
     */
    @Override
    public boolean delete(String key) {
        //构造一个带指定Zone对象的配置类
        Configuration cfg = new Configuration(Zone.zone2());
        BucketManager bucketMgr = null;
        try {
            Auth auth = getAuth();
            bucketMgr = new BucketManager(auth, cfg);
            Response delete = bucketMgr.delete(qiNiuConfig.getBucket(), key);
            return delete.isOK();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

}